React Concurrent Mode感想スレ
APIの規模が小さいので割とすぐにフル機能のものが作れて楽なのだ
規模は小さいが、
OAuth2ベースの認証機構
データの正規化(タイムライン表示)
Infinite Loadingを含むページング処理
ストリームの管理
みたいなデータ取得周りの難しさは網羅している
反面、複雑なフォームみたいなのはない
思うこと
データ取得を上位階層に持ち上げるのが難しい
というかデータを利用するコンポーネントとデータ取得が離れているのが気に食わない
それコンポーネントじゃないだろという気持ちになったり
Prop Drillingの再来じゃん…って気持ちになったり
まあContextで解決できるのだが
これをするためにルータを書く必要がある
大変
解決した
コンポーネントの直上にgetInitialPropsを定義(これがFragmentに相当する) Propsの定義にReturnType<typeof getInitialProps>を使うと非常に便利
そのコンポーネントを使うコンポーネントにも同様にgetInitialPropsを書き、下のコンポーネントのgetInitialPropsを合成して書く
これをSuspense直下までくり返し、Suspenseの上でgetInitialPropsを呼べば、全てのコンポーネントに必要なリソースを集めることに成功する ページコンポーネントのgetInitialPropsをルータに渡したりするといい感
こんなのでうまくいくのか?という気がするが、Propsの型定義によって 間違ったことをすればすぐにエラーになってくれる
コンポーネントとデータのコロケーションをサポートする?
今回はgetInitialPropsをうまく書くためにAPIクライアントとキャッシュを結びつける層を用意した
これが相当するのかも
Reduxを封じられている
でもこれなしでどうやって無駄な再レンダーを抑制しつつデータの正規化を行うんだろうという気持ち 正規化しないと欲しいレンダリング結果を得られないシーンがいくつか存在する
正規化が必要なオブジェクトは数百くらいにもなり得るのでContextで解決できるのか?という気持ちになる
まあContext & React.memoでいけそうな気もする
という夢を見ていた
確かにReduxストアはプレーンなJSオブジェクトしか受け付けないのでここに非同期管理オブジェクトを入れることはできない
しかし、ReduxのSelectorはデータへの参照として機能する
ということはLodable<Selector>みたいなものを非同期処理で作って返せばReduxストアは処理完了後のプレーンなJSオブジェクトだけ見ていることができる
code:tsx
export const getInitialProps = (store: Store) => {
/* 何らかの非同期処理 */
const selectorLoadable: Loadable<Selector>
return {
selectorLoadable
}
}
export const Component = ({ selectorLoadable }) => {
const data = useSelector(selectorLoadable.read())
/* 描画処理 */
}
GraphQLって便利なんだなあ
Fragmentが強い
初回ロードでは必要なクエリを構成する要素として
マウント後はリソースの更新を追従するためのキャッシュからのセレクタとして動作する